﻿/*
COPYRIGHT (C) 2009 EPISERVER AB

THIS FILE IS PART OF REMOTE PAGE PROVIDER FOR EPISERVER CMS.
REMOTE PAGE PROVIDER FOR EPISERVER CMS IS FREE SOFTWARE: YOU CAN REDISTRIBUTE IT AND/OR MODIFY IT UNDER THE TERMS OF THE GNU LESSER GENERAL PUBLIC LICENSE VERSION v2.1 AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION.

REMOTE PAGE PROVIDER FOR EPISERVER CMS IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU LESSER GENERAL PUBLIC LICENSE FOR MORE DETAILS.
YOU SHOULD HAVE RECEIVED A COPY OF THE GNU LESSER GENERAL PUBLIC LICENSE ALONG WITH REMOTE PAGE PROVIDER FOR EPISERVER CMS]. IF NOT, SEE <HTTP://WWW.GNU.ORG/LICENSES/>.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Hosting;
using System.IO;
using EPiServer.Web.Hosting;
using EPiServer.Security;

namespace EPiServer.Labs.RemoteProvider
{
    public class RemoteUnifiedFile : UnifiedFile
    {

        RemoteFileInfo          _remoteFileInfo;
        IRemoteProvider         _remoteFileServer;
        RemoteUnifiedDirectory  _parent;
        RemoteFileStream        _nativeStream;

        /// <summary>
        /// Initializes a new instance of the <see cref="RemoteUnifiedFile"/> class.
        /// </summary>
        /// <param name="remotFileServer">The remot file server.</param>
        /// <param name="parent">The parent.</param>
        /// <param name="provider">The provider.</param>
        /// <param name="remoteFileInfo">The remote file info.</param>
        public RemoteUnifiedFile(
                    IRemoteProvider remotFileServer, 
                    RemoteUnifiedDirectory  parent, 
                    VirtualPathUnifiedProvider provider, 
                    RemoteFileInfo remoteFileInfo): base((UnifiedDirectory) parent, provider, remoteFileInfo.VirtualPath, provider.BypassAccessCheck)
        {
            _remoteFileServer = remotFileServer;
            _remoteFileInfo = remoteFileInfo;
            _nativeStream = new RemoteFileStream(_remoteFileServer, _remoteFileInfo);
            _parent = parent;
        }

        #region VirtualFile

        /// <summary>
        /// Opens this instance.
        /// </summary>
        /// <returns></returns>
        public override Stream Open()
        {
            return Open(FileMode.Open, FileAccess.Read, FileShare.Read);
        }

        #endregion


        #region UnifiedFile

        /// <summary>
        /// Opens the specified mode.
        /// </summary>
        /// <param name="mode">The mode.</param>
        /// <param name="access">The access.</param>
        /// <param name="share">The share.</param>
        /// <returns></returns>
        public override Stream Open(FileMode mode, FileAccess access, FileShare share)
        {
            RemoteFileInfo fileInfo;
            if (mode == FileMode.Open && access == FileAccess.Read)
            {
                _remoteFileServer.Open(LocalVirtualPathToRemoteVirtualPath(_remoteFileInfo.VirtualPath), out fileInfo);
                _remoteFileInfo.Content = fileInfo.Content;
            }
            return _nativeStream.Open(mode, access, share, _remoteFileInfo);
        }


        /// <summary>
        /// Gets the parent.
        /// </summary>
        /// <value>The parent.</value>
        public override UnifiedDirectory Parent
        {
            get
            {
                return (UnifiedDirectory)_parent;
            }
        }

        /// <summary>
        /// Gets the summary.
        /// </summary>
        /// <value>The summary.</value>
        public override IUnifiedSummary Summary
        {
            get
            {
                return new RemoteUnifiedSummary(_remoteFileInfo.UnifiedSummaryData);
            }
        }

        /// <summary>
        /// Gets the extension.
        /// </summary>
        /// <value>The extension.</value>
        public override string Extension
        {
            get
            {
                return _remoteFileInfo.Extension;
            }
        }

        /// <summary>
        /// Gets the local path.
        /// </summary>
        /// <value>The local path.</value>
        public override string LocalPath
        {
            get
            {
                return "";
            }
        }

        /// <summary>
        /// Gets the display name of the virtual resource.
        /// </summary>
        /// <value></value>
        /// <returns>The display name of the virtual file.</returns>
        public override string Name
        {
            get
            {
                return _remoteFileInfo.Name;
            }
        }

        /// <summary>
        /// Gets the length.
        /// </summary>
        /// <value>The length.</value>
        public override long Length
        {
            get
            {
                return _remoteFileInfo.Length;
            }
        }

        /// <summary>
        /// Gets the created.
        /// </summary>
        /// <value>The created.</value>
        public override DateTime Created
        {
            get
            {
                return _remoteFileInfo.Created;
            }
        }

        /// <summary>
        /// Gets the changed.
        /// </summary>
        /// <value>The changed.</value>
        public override DateTime Changed
        {
            get
            {
                return _remoteFileInfo.Changed;
            }
        }

        /// <summary>
        /// Gets the permanent link virtual path.
        /// </summary>
        /// <value>The permanent link virtual path.</value>
        public override string PermanentLinkVirtualPath
        {
            get
            {
                // Return null to indicate that we do not support permanent links
                return null;
            }
        }
        #endregion



        #region Helper Method
        /// <summary>
        /// Remotes the virtual path to local virtual path.
        /// </summary>
        /// <param name="remoteVirtualPath">The remote virtual path.</param>
        /// <returns></returns>
        private string RemoteVirtualPathToLocalVirtualPath(string remoteVirtualPath)
        {
            RemoteVirtualPathProvider remoteProvider = Provider as RemoteVirtualPathProvider;
            if (remoteProvider != null)
            {
                return remoteProvider.RemoteVirtualPathToLocalVirtualPath(remoteVirtualPath);
            }
            return remoteVirtualPath;
        }

        /// <summary>
        /// Locals the virtual path to remote virtual path.
        /// </summary>
        /// <param name="localVirtualPath">The local virtual path.</param>
        /// <returns></returns>
        private string LocalVirtualPathToRemoteVirtualPath(string localVirtualPath)
        {
            RemoteVirtualPathProvider remoteProvider = Provider as RemoteVirtualPathProvider;
            if (remoteProvider != null)
            {
                return remoteProvider.LocalVirtualPathToRemoteVirtualPath(localVirtualPath);
            }
            return localVirtualPath;
        }

        #endregion

    }
}

